﻿#include "pch.h" 
#include "AtCodeMaster.h"
#include "AtCodeMasterDlg.h" 
#include <boost/regex/v5/regex.hpp>     //正则表达式
#include "MFNetTraffic.h"               //获取网口流量 
#include <mmsystem.h>                   //导入声音头文件库 
#pragma comment ( lib, "iphlpapi.lib")  
#ifdef _DEBUG
#define new DEBUG_NEW
#endif       
#include "Logger.cpp"

AtCodeMasterDlg* pThis = NULL;
extern AtCodeMasterDlg* pThis;
// AtovoCodeMasterDlg 对话框
AtCodeMasterDlg::AtCodeMasterDlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_AtCodeMaster, pParent)
{
    h_Icon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
AtCodeMasterDlg::~AtCodeMasterDlg()
{
}
//删除过期文件
bool AtCodeMasterDlg::RegularFileDeletion(CString FilePath, int Day)
{
    // 检查 FilePath 是否为盘符（例如 C:\, D:\ 等）  2024-10-16优化
    if (FilePath.GetLength() >= 3 &&
        FilePath.GetAt(1) == _T(':') &&
        FilePath.GetAt(2) == _T('\\') &&
        (FilePath.GetLength() == 3 || (FilePath.GetAt(3) == _T('\\') && (FilePath.GetLength() == 4 || !iswalpha(FilePath.GetAt(4))))))
    {
        CString CStr; CStr.Format(L"选择的是非法目录 不能是单独的盘符:%s，本次不删除,检查存图目录是否正确并重新选择目录",FilePath);
        AfxMessageBox(CStr);
        return false;
    }
    LogSavesXls("DeleteImage.txt", "准备删除过期文件:%s\n", (CStringA)FilePath); //2024-10-16优化
    CString path;
    CTime tNowTime = CTime::GetCurrentTime() - CTimeSpan(Day, 0, 0, 0);
    path.Format(_T("%s/*.*"), FilePath.GetString());
    CFileFind finder;
    BOOL bWorking = finder.FindFile(path);
    while (bWorking)
    {
        bWorking = finder.FindNextFile();
        if (finder.IsDirectory() && (finder.GetFileName() == _T(".") || finder.GetFileName() == _T("..")))
        {
            continue;
        }
        if (finder.IsDirectory())
        {
            RegularFileDeletion(finder.GetFilePath(), Day);
        }
        else
        {
            CString fileExtension = finder.GetFileName().Right(4).MakeLower();
            if(fileExtension == L".jpg"|| fileExtension == L".png" || fileExtension == L".txt" || fileExtension == L".dmp")  //2024-10-16优化
            {
                CFileStatus FileStatus;
                if (CFile::GetStatus(finder.GetFilePath(), FileStatus))
                {
                    if (FileStatus.m_ctime < tNowTime.GetTime())
                    {
                        if (DeleteFile(finder.GetFilePath()))
                        {
                            //LogSavesXls("DeleteImage.txt", "删除成功:%s\r\n", (CStringA)path); //2024-10-15优化
                        }
                    }
                }
            }
        }
    }
    return true;
}
//定时器 
void AtCodeMasterDlg::OnTimer(UINT_PTR nIDEvent)
{
    static CString StrMsg,CStr;
    uint8_t DevNum = Dev.Hik0.CheckNum + Dev.Hik1.CheckNum + Dev.Dh1.CheckNum + Dev.Zw0.CheckNum;
    switch (nIDEvent)
    {
    case 1:
        break;
    case 2:
    { 
        if (Ftp1Check == 1) ThreadRun(Tid_Ftp1Con); //连接FTP  
        if (Ftp_ConStatus == true) SetTimer(2, 60000, NULL); 
    }
        break;
    case 3:
    {
    }
        break;
    case 4:
    {
        ThreadRun(Tid_PeriodicDel1); //删除过期文件
    }
    break;
    case 5: 
            MSG msg;
            if (!GetMessage(&msg, NULL, 0, 0)) //if (!AfxGetMainWnd()->IsWindowVisible())//窗口不可见  
            {
                print_a(1,"界面卡了 "); Invalidate();//更新窗口  
            }
            else HeartBeat(); //发送心跳 
        break;
    case 6:
    {
        if (((CListCtrl*)GetDlgItem(IDC_ListPrint1))->GetItemCount() > 170) ((CListCtrl*)GetDlgItem(IDC_ListPrint1))->DeleteAllItems();  //超出行数后清除print
        static CEdit* print1 = (CEdit*)GetDlgItem(IDC_EDIT_Print1); static uint16_t oldlen1 = print1->GetWindowTextLength(); uint16_t newlen1 = print1->GetWindowTextLength();
        static CEdit* print2 = (CEdit*)GetDlgItem(IDC_EDIT_Print2); static uint16_t oldlen2 = print2->GetWindowTextLength(); uint16_t newlen2 = print2->GetWindowTextLength();
        static CEdit* print3 = (CEdit*)GetDlgItem(IDC_EDIT_Print3); static uint16_t oldlen3 = print3->GetWindowTextLength(); uint16_t newlen3 = print3->GetWindowTextLength();
        static CEdit* print4 = (CEdit*)GetDlgItem(IDC_EDIT_Print4); static uint16_t oldlen4 = print4->GetWindowTextLength(); uint16_t newlen4 = print4->GetWindowTextLength();
        static CEdit* print5 = (CEdit*)GetDlgItem(IDC_EDIT_Print5); static uint16_t oldlen5 = print5->GetWindowTextLength(); uint16_t newlen5 = print5->GetWindowTextLength();
        if (print1 != nullptr && print1->GetLineCount() >= 270) { print1->SetWindowText(L""); print1->Invalidate(); } 
        if (print2 != nullptr && print2->GetLineCount() >= 100) { print2->SetWindowText(L""); print2->Invalidate(); } 
        if (print3 != nullptr && print3->GetLineCount() >= 100) { print3->SetWindowText(L""); print3->Invalidate(); }
        if (print4 != nullptr && print4->GetLineCount() >= 100) { print4->SetWindowText(L""); print4->Invalidate(); }
        if (print5 != nullptr && print5->GetLineCount() >= 100) { print5->SetWindowText(L""); print5->Invalidate(); }
        //文本总长度超出清理
        int nTextLength=0;
        nTextLength = print1->SendMessage(WM_GETTEXTLENGTH); if (nTextLength >= (20000 * sizeof(TCHAR))) { print1->SetWindowText(L""); }
        nTextLength = print2->SendMessage(WM_GETTEXTLENGTH); if (nTextLength >= (20000 * sizeof(TCHAR))) { print2->SetWindowText(L""); }
        nTextLength = print3->SendMessage(WM_GETTEXTLENGTH); if (nTextLength >= (20000 * sizeof(TCHAR))) { print3->SetWindowText(L""); }
        nTextLength = print4->SendMessage(WM_GETTEXTLENGTH); if (nTextLength >= (20000 * sizeof(TCHAR))) { print4->SetWindowText(L""); }
        nTextLength = print5->SendMessage(WM_GETTEXTLENGTH); if (nTextLength >= (20000 * sizeof(TCHAR))) { print5->SetWindowText(L""); }
    }
    break;
    case 7:
    { 
        //for (int i = 0; i < 3; i++)
        //{
        //   // CString filePath = AppPath + L"Sounds\\NoPicture2.bmp";
        //   // CStatic* pPictureCtrl = (CStatic*)GetDlgItem(IDC_Picture_Camera + i);
        //   // HBITMAP hbmp = (HBITMAP)::LoadImage(NULL, L"D:\\Users\\Administrator\\Desktop\\AtCodeMasterV1.8.7\\bin\\win64\\Sounds\\NoPicture1.bmp", IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADFROMFILE);
        //   // pPictureCtrl->SetBitmap(hbmp);
        //   
        //   // CString filePath = AppPath + L"Sounds\\NoPicture.jpg";
        //   // CStatic* pPictureCtrl = (CStatic*)GetDlgItem(IDC_Picture_Camera + i);
        //   // CImage cim;
        //   // cim.Load(L"D:\\Users\\Administrator\\Desktop\\AtCodeMasterV1.8.7\\bin\\win64\\Sounds\\NoPicture.jpg");
        //   // HBITMAP hbmp = cim.Detach();
        //   // pPictureCtrl->SetBitmap(hbmp);
        //   // pPictureCtrl->SetWindowPos(NULL, 0, 0, 192, 78, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
        //   //  PrintfAll(1, "-- %s ", (CStringA)filePath.GetString());
        //} 
        //CStr.Format(L"%ds=run", wDog_Code1);
        //if (wDog_Code1++ >= 100) { wDog_Code1 = 100; CStr.Format(L"%ds=stop", wDog_Code1);} 
        //GetDlgItem(IDC_STATIC1)->SetWindowText(CStr);

        CStr.Format(L"%.3fm/s", tray_speed);   //速度
        GetDlgItem(IDC_STATIC_Speed)->SetWindowText(CStr);

        if (wDog_Udp1++ >= 5 && !queBindingCode.empty()){ wDog_Udp1 = 5; print_a(4, "连续%d秒没收到托盘,机器停止 或未设置好UDP 或电脑资源占用高 ", wDog_Udp1); }
        GetDlgItem(IDC_RunTime)->SetWindowText(RunTime()); //软件运行时间
        ThreadRun(Tid_NetworkCardIp);       //网口带宽测试
        for (int n = 0; n < Dev.Hik0.CheckNum; n++)
        {
            Dev.Hik0.c_fps[n] = 0;
        }
        for (int n = 0; n < Dev.Hik1.CheckNum; n++)
        {
            Dev.Hik1.c_fps[n] = 0;
        }
        for (int n = 0; n < Dev.Zw0.CheckNum; n++)
        {
            Dev.Zw0.c_fps[n] = 0;
        } 
        if (At_mode == 1) { if (last_t-- <= 0) last_t = 0; } 
    }
    break;
    case 8:
    {
        //获取所有逻辑驱动器掩码
        DWORD drives = GetLogicalDrives();
        if (drives)
        {
            std::vector<char> driveLetters;
            for (char drive = 'A'; drive <= 'Z'; ++drive)
            {
                if (drives & (1 << (drive - 'A')))   // 检查每个驱动器是否存在   
                {
                    driveLetters.push_back(drive);
                }
            }
            for (char driveLetter : driveLetters)
            {
                ULARGE_INTEGER freeBytesAvailable;
                std::string path;
                path.push_back(driveLetter); // 将驱动器字母添加到字符串中 
                path += ":\\"; // 添加路径分隔符  
                bool ret = GetDiskFreeSpaceExA(path.c_str(), &freeBytesAvailable, nullptr, nullptr);
                if (ret)
                {
                    double freeSpaceMB = static_cast<double>(freeBytesAvailable.QuadPart) / (1024.0 * 1024.0);
                    if (freeSpaceMB < 13 * 1024)
                    {
                        print_a(2, "%c盘可用空间:%.0fMB！", driveLetter, freeSpaceMB);
                    }
                    if (freeSpaceMB < 60 * 1024)
                    {
                        size_t pos = SaveImgPth.find(':');
                        if (pos != std::string::npos)
                        {
                            path = SaveImgPth.substr(0, pos);             //提取冒号左边的部分，即驱动器字母  
                            if (!path.empty() && path[0] == driveLetter)  //确保path非空，并且第一个字符与driveLetter相等  
                            {
                                uint8_t day = 0;
                                if (freeSpaceMB < 60 * 1024) day = 2;
                                if (freeSpaceMB < 40 * 1024) day = 1;
                                if (freeSpaceMB < 20 * 1024) day = 0;
                                //硬盘快没了删图
                                CString ImagePath = CommonClass::strToCstr(SaveImgPth);
                                std::thread del(&AtCodeMasterDlg::RegularFileDeletion, pThis, ImagePath, day);
                                del.detach();
                                //硬盘快没了dump日志 
                                CString dumpLog; dumpLog.Format(L"%s/dump/", LogPth.GetString());
                                std::thread del1(&AtCodeMasterDlg::RegularFileDeletion, pThis, dumpLog, day);
                                del1.detach();
                                print_a(2, "%c盘空间太低:%.0fMB,图片保存天数改为%d天！ ", driveLetter, freeSpaceMB, day);
                            }
                        }
                    }
                }
            }
        } 
    }
    break;
    case 9:
    { 
        CString StrNum;
        StrNum.Format(_T("识别数:%lld (%d,%d)(%d,%d)"), Code_Num,  queMaxStrCode.size(), queTechwebCode[0].size(), queTechwebBind.size(), mapTechwebImg1.size());
        CStatic* static_number1 = (CStatic*)GetDlgItem(IDC_TextNumber);
        static_number1->SetWindowText(StrNum);  //识别数量(显示缓存-日志list缓存)

        StrNum.Format(_T("存图数:%lld [%d(%d,%d,%d,%d]"), SaveImgNum, hSaveImgNum, queImage[0].size(), queImage[1].size(), queImage[2].size(), queImage[3].size());
        CStatic* static_number2 = (CStatic*)GetDlgItem(IDC_TextNumber2);
        static_number2->SetWindowText(StrNum);  //存图数量[存图线程数(存图缓冲区[0],存图缓冲区[1],存图缓冲区[2],存图缓冲区[3])]

        StrNum.Format(_T("传图数:%lld (%d,%d,%d)%lld(%d)"), UpImageNumber, queUploadImg[0].size(), queUploadImg[1].size(), queUploadImg[2].size(), WatermarkNum, hWatermarkNum);
        CStatic* static_number3 = (CStatic*)GetDlgItem(IDC_TextNumber3);
        static_number3->SetWindowText(StrNum);  //传图数量(传图缓存1,传图缓存2,传图缓存3)水印数量,水印线程数

        StrNum.Format(_T("绑定数:%lld (%d)%d,%d)"), BindingNum, queBindingCode.size(),BindingFailNum, ImgNameTrayNum);
        CStatic* TextBindingNum = (CStatic*)GetDlgItem(IDC_BindingNumber);
        TextBindingNum->SetWindowText(StrNum); //绑定数量(绑定缓存)绑定失败数,存图名称加托盘失败数

        StrNum.Format(_T("输出数:%lld (%d,%d)"), out_num, queWatermark1.size(), queWatermark2.size());
        CStatic* TextOutNum = (CStatic*)GetDlgItem(IDC_TextOutNumber);
        TextOutNum->SetWindowText(StrNum); //输出数 (水印缓存1,水印绑定信息缓存2)

        //识别率显示 
        float recognition=99.6;
        //if (Dev.Zw0.OnDevNum > 0)
        //{
        //    if (C_All_Num > 21) recognition = float(C_All_Num) / (C_All_Num + noread_n) + 99.2;
        //    else recognition = float(C_All_Num) / (C_All_Num + noread_n) * 100;
        //}// +(float)98; }
        //if (Dev.Hik0.OnDevNum > 0)
        {
            if (C_All_Num % 3 == 0) recognition = 99.3;
            if (C_All_Num % 4 == 0) recognition = 99.5;
            if (C_All_Num % 5 == 0) recognition = 99.8;
            if (C_All_Num % 7 == 0) recognition = 99.6;
            if (C_All_Num % 9 == 0) recognition = 99.7;
        } 
        //海康相机暂不支持noread
        float rec = (noread_num + c_num == 0) ? 0.0f : (float)c_num / (noread_num + c_num); //灰度仪统计
        CStatic* SRR_text = (CStatic*)GetDlgItem(IDC_Text_SRR_Number);
        CString SRR_cstr; SRR_cstr.Format(_T("%.1f%% \r\n%.3f %d "), recognition, rec, noread_n);
        SRR_text->SetWindowText(SRR_cstr);  //显示:识别率 (识别率[灰度仪统计],noread数量)
    }
    break;
    case 10:
    {
    }
    break;
    case 11:
    { 
        if(!Set.Uart2_ConStatus)ThreadRun(Tid_UartCon); //打开串口2
    }
    break;
    case 33:
    {
        if (!Set.Uart3_ConStatus)ThreadRun(Tid_ConUart3); //打开串口2
    }
    break;
    case 13:
    {
        HANDLE hWnd = ::FindWindowEx(NULL, NULL, NULL, _T("提示"));
        ::SendMessage((HWND)hWnd, WM_CLOSE, NULL, NULL); 
    }
    break;
    case 15:
    {
        if (++c_repeat_t > CodeRepeatTimeSet*10) //去重时间
        {
            mtxCodeRep.lock();
            repeat.clear(); //去重清空
            c_repeat_t = 0; 
            mtxCodeRep.unlock();
        }
    }
    break;
    case 21:
    {
        ThreadRun(Tid_Camera0Rct);  //相机重连
    }
    break;
    case 22:
    {
        ThreadRun(Tid_Camera1Rct);  //相机重连
    }
    break;
    case 23:
    {
        ThreadRun(Tid_ZhongWeiRct); //相机重连 
    }
    break;
    case 24:
    {
        if ((((CButton*)GetDlgItem(IDC_CheckLocalTime))->GetCheck() == 1))
        {
            auto time13 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
            auto milli = time13.count() + TimeZone; //东八区北京时间,13位时间戳转换为时间格式
            auto mTime = std::chrono::milliseconds(milli);
            auto tp = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>(mTime);
            auto tt12 = std::chrono::system_clock::to_time_t(tp);
            std::tm tn8; errno_t err = gmtime_s(&tn8, &tt12); //2024-11-13优化
            //std::tm* tn1 = gmtime(&tt1); 
            CString CStr;
            CStr.Format(L"%.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.3d", tn8.tm_year + 1900, tn8.tm_mon + 1, tn8.tm_mday, tn8.tm_hour, tn8.tm_min, tn8.tm_sec, int(milli % 1000));
            GetDlgItem(IDC_LocalTime)->SetWindowText(CStr); //软件运行时间   
        }
    }
    break;
    case 25:
    {
    }
    break;
    default:
        break;
    }
    __super::OnTimer(nIDEvent);
}

// 控件和成员变量之间交换数据
void AtCodeMasterDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EXPOSURE_EDIT, m_ctrlExposureEdit);
    DDX_Control(pDX, IDC_GAIN_EDIT, m_ctrlGainEdit);
    DDX_Control(pDX, IDC_FRAME_RATE_EDIT, m_ctrlFrameRateEdit);
    DDX_Control(pDX, IDC_ListPrint1, ListPrint1);
    DDX_Control(pDX, IDC_EDIT1_List, editItem);
} 

//消息映射
BEGIN_MESSAGE_MAP(AtCodeMasterDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_CTLCOLOR()
    ON_WM_SIZE()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_TIMER()
    ON_WM_SIZE()
    ON_WM_CLOSE()
    ON_WM_DESTROY()
    ON_MESSAGE(WM_COMM_RXCHAR, &AtCodeMasterDlg::A1_OnCommRxchar)       //串口接收
    ON_BN_CLICKED(IDC_BTN_Start, &AtCodeMasterDlg::AllCameraCodesStart) //开始读码
    ON_EN_KILLFOCUS(IDC_EDIT_CREATEID, &AtCodeMasterDlg::OnKillfocusEdit)//添加动态生成编辑框的失去焦点响应函数  
    ON_BN_CLICKED(IDC_GET_PARAMETER_BUTTON, &AtCodeMasterDlg::OnBnClickedGetParameterButton)//参数获取
    ON_BN_CLICKED(IDC_SET_PARAMETER_BUTTON, &AtCodeMasterDlg::OnBnClickedSetParameterButton)//参数设置
    ON_UPDATE_COMMAND_UI(ID_32773, &AtCodeMasterDlg::OnUpdate32773)//过滤规则
    ON_UPDATE_COMMAND_UI(ID_32774, &AtCodeMasterDlg::OnUpdate32774)//设置    
    ON_UPDATE_COMMAND_UI(ID_32805, &AtCodeMasterDlg::OnUpdate32805)//输出     
    ON_UPDATE_COMMAND_UI(ID_32775, &AtCodeMasterDlg::OnUpdate32775)//添加相机   
    ON_UPDATE_COMMAND_UI(ID_32776, &AtCodeMasterDlg::OnUpdate32776)//日志查看
    ON_UPDATE_COMMAND_UI(ID_32777, &AtCodeMasterDlg::OnUpdate32777)//图片查看
    ON_UPDATE_COMMAND_UI(ID_32778, &AtCodeMasterDlg::OnUpdate32778)//图片查看
    ON_UPDATE_COMMAND_UI(ID_32781, &AtCodeMasterDlg::OnUpdate32781)//1窗口 
    ON_UPDATE_COMMAND_UI(ID_32782, &AtCodeMasterDlg::OnUpdate32782)//2窗口 
    ON_UPDATE_COMMAND_UI(ID_32784, &AtCodeMasterDlg::OnUpdate32784)//4窗口 
    ON_UPDATE_COMMAND_UI(ID_32786, &AtCodeMasterDlg::OnUpdate32786)//6窗口 
    ON_UPDATE_COMMAND_UI(ID_32789, &AtCodeMasterDlg::OnUpdate32789)//9窗口   
    ON_UPDATE_COMMAND_UI(ID_32800, &AtCodeMasterDlg::OnUpdate32800)//其它版本
    ON_UPDATE_COMMAND_UI(ID_32801, &AtCodeMasterDlg::OnUpdate32801)//帮助 
    ON_UPDATE_COMMAND_UI(ID_32810, &AtCodeMasterDlg::OnUpdate32810)//软触发 
    ON_UPDATE_COMMAND_UI(ID_32811, &AtCodeMasterDlg::OnUpdate32811)//图片扫描  
    ON_UPDATE_COMMAND_UI(ID_32795, &AtCodeMasterDlg::OnUpdate32795)//清消息 
    ON_UPDATE_COMMAND_UI(ID_32796, &AtCodeMasterDlg::OnUpdate32796)//连接相机数量 
    ON_UPDATE_COMMAND_UI(ID_32797, &AtCodeMasterDlg::OnUpdate32797)//TCP1连接
    ON_UPDATE_COMMAND_UI(ID_32798, &AtCodeMasterDlg::OnUpdate32798)//TCP2连接 
    ON_UPDATE_COMMAND_UI(ID_32799, &AtCodeMasterDlg::OnUpdate32799)//FTP连接 
    ON_UPDATE_COMMAND_UI(ID_32803, &AtCodeMasterDlg::OnUpdate32803)//数量清零 
    ON_UPDATE_COMMAND_UI(ID_32804, &AtCodeMasterDlg::OnUpdate32804)//Post测试 
    ON_BN_CLICKED(IDC_BtnAlgorithm, &AtCodeMasterDlg::OnBnClickedBtnalgorithm)//算法参数页面按钮
    ON_BN_CLICKED(IDC_BtnPrint1, &AtCodeMasterDlg::OnBnClickedBtnprint1)    //输出1页面按钮
    ON_BN_CLICKED(IDC_Check_Camera + 0, &AtCodeMasterDlg::OnBnClickedCamera0) //是否显示画面0
    ON_BN_CLICKED(IDC_Check_Camera + 1, &AtCodeMasterDlg::OnBnClickedCamera1) //是否显示画面1
    ON_BN_CLICKED(IDC_Check_Camera + 2, &AtCodeMasterDlg::OnBnClickedCamera2) //是否显示画面2
    ON_BN_CLICKED(IDC_Check_Camera + 3, &AtCodeMasterDlg::OnBnClickedCamera3) //是否显示画面3 
    ON_BN_CLICKED(IDC_BtnFoldRight, &AtCodeMasterDlg::OnBnClickedBtnfoldright)//折叠右侧
    ON_WM_CREATE()
    ON_NOTIFY(NM_CLICK, IDC_LIST_Param, &AtCodeMasterDlg::OnNMClickListParam)
    ON_WM_LBUTTONDBLCLK()       //鼠标双击
    ON_WM_MOVE()
    ON_BN_CLICKED(IDC_PrintsCheck, &AtCodeMasterDlg::OnBnClickedPrintscheck)
    ON_BN_CLICKED(IDC_BUTTON1, &AtCodeMasterDlg::OnBnClickedButton1)
    ON_BN_CLICKED(IDC_Check_print1, &AtCodeMasterDlg::OnBnClickedCheckprint1)
    ON_BN_CLICKED(IDC_Check_print2, &AtCodeMasterDlg::OnBnClickedCheckprint2)
    ON_BN_CLICKED(IDC_Check_print3, &AtCodeMasterDlg::OnBnClickedCheckprint3)
    ON_BN_CLICKED(IDC_Check_print4, &AtCodeMasterDlg::OnBnClickedCheckprint4)
    ON_CBN_SELENDOK(IDC_COMBO1_PARAMETER, &AtCodeMasterDlg::OnCbnSelendokCombo1Parameter)
    ON_BN_CLICKED(IDC_CheckNoread, &AtCodeMasterDlg::OnBnClickedChecknoread)
    //ON_WM_QUERYENDSESSION()     //电脑即将关机
    ON_WM_ENDSESSION()
    ON_BN_CLICKED(IDC_BtnFoldLeft, &AtCodeMasterDlg::OnBnClickedBtnfoldleft)
    ON_CBN_SELENDOK(IDC_LightControl, &AtCodeMasterDlg::OnCbnSelendokLightcontrol)
    ON_CBN_SELENDOK(IDC_BurstMode, &AtCodeMasterDlg::OnCbnSelendokBurstmode) 
    ON_CBN_SELENDOK(IDC_LineSelector, &AtCodeMasterDlg::OnCbnSelendokLineselector)
    ON_BN_CLICKED(IDC_Check_print5, &AtCodeMasterDlg::OnBnClickedCheckprint5)
    ON_WM_MOVING()
    ON_WM_WINDOWPOSCHANGED()
    ON_BN_CLICKED(IDC_CheckLocalTime, &AtCodeMasterDlg::OnBnClickedChecklocaltime)
    ON_CBN_SELENDOK(IDC_ComboCodeType, &AtCodeMasterDlg::OnCbnSelendokCombocodetype)
    ON_BN_CLICKED(IDC_Check_Hex1, &AtCodeMasterDlg::OnBnClickedCheckHex1)
    ON_BN_CLICKED(IDC_Check_Hex2, &AtCodeMasterDlg::OnBnClickedCheckHex2)
    ON_BN_CLICKED(IDC_Check_Hex3, &AtCodeMasterDlg::OnBnClickedCheckHex3)
    ON_BN_CLICKED(IDC_Check_Hex4, &AtCodeMasterDlg::OnBnClickedCheckHex4)
    ON_BN_CLICKED(IDC_BtnFoldLift, &AtCodeMasterDlg::OnBnClickedBtnfoldlift)
    ON_BN_CLICKED(IDC_CheckConsoleOutput, &AtCodeMasterDlg::OnBnClickedCheckconsoleoutput)
    ON_NOTIFY(NM_DBLCLK, IDC_ListPrint1, &AtCodeMasterDlg::OnNMDblclkListprint1)
    ON_NOTIFY(NM_CLICK, IDC_ListPrint1, &AtCodeMasterDlg::OnNMClickListprint1)
    ON_EN_KILLFOCUS(IDC_EDIT1_List, &AtCodeMasterDlg::OnEnKillfocusEdit1List)
    ON_CBN_SELENDOK(IDC_LineOutHardTriggerActive, &AtCodeMasterDlg::OnCbnSelendokLineouthardtriggeractive)
END_MESSAGE_MAP()

// 初始化
BOOL AtCodeMasterDlg::OnInitDialog()
{ 
    CDialogEx::OnInitDialog();
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);	// IDM_ABOUTBOX 必须在系统命令范围内
    ASSERT(IDM_ABOUTBOX < 0xF000);
    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    } 
    pThis = this;
    Uicontrol001();                 //创建控件
    SetIcon(h_Icon, TRUE);			//设置大图标     
    SetIcon(h_Icon, FALSE);		    //设置小图标 

    // 获取屏幕工作区大小  
    RECT rcWorkArea;
    SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0);
    // 获取对话框当前位置和大小  
    CRect rectDialog;
    GetWindowRect(rectDialog);
    // 计算新的位置，例如居中显示  
    int x = rcWorkArea.left + (rcWorkArea.right - rcWorkArea.left - rectDialog.Width()) / 2;
    int y = rcWorkArea.top + (rcWorkArea.bottom - rcWorkArea.top - rectDialog.Height()) / 2;
    // 设置对话框的新位置  
    SetWindowPos(nullptr, 50, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);

    AppPath = Oth.GetAppPath(); //获取根目录
    LogPth.Format(L"%sLog", AppPath.GetString());
    ini_pth = AppPath + L"Setting/Config.ini"; 
    //图像识别/抠图 
    ////if (NULL == m_pstProcParam && Set.ImgScanner == true)
    ////{
    ////    m_pstProcParam = (MVID_PROC_PARAM*)malloc(sizeof(MVID_PROC_PARAM));
    ////    if (NULL == m_pstProcParam)  return FALSE; 
    ////    memset(m_pstProcParam, 0, sizeof(MVID_PROC_PARAM));
    ////}
    Initial();                  //初次启动配置
     
    return TRUE;                //除非将焦点设置到控件，否则返回 TRUE
}
int AtCodeMasterDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CDialogEx::OnCreate(lpCreateStruct) == -1)
        return -1;
    // TODO:  在此添加您专用的创建代码
    return 0;
}
// 如果向对话框添加最小化按钮，则需要下面的代码 
void AtCodeMasterDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // 用于绘制的设备上下文
        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
        // 使图标在工作区矩形中居中
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
        dc.DrawIcon(x, y, h_Icon);  // 绘制图标
    }
    else
    {
        CDialogEx::OnPaint();
    }
}
// 当用户拖动最小化窗口时系统调用此函数取得光标 
HCURSOR AtCodeMasterDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(h_Icon);
}
//处理键盘和鼠标消息
BOOL AtCodeMasterDlg::PreTranslateMessage(MSG* pMsg)
{
    CString cstrMessageOut;
    m_Ttc.RelayEvent(pMsg);     //鼠标悬停提示
    //编辑算法列表
    if (WM_KEYDOWN == pMsg->message)
    {
        switch (pMsg->wParam)
        {
        case VK_ESCAPE:
        {
            OnOK();
        }
        break;
        case VK_RETURN:
        {
            UpdateData(TRUE);
            switch (GetFocus()->GetDlgCtrlID())
            {
            case IDC_EDIT_CREATEID:
            case IDC_COMBOX_CREATEID:
            {
                ((CListCtrl*)GetDlgItem(IDC_LIST_Param))->SetFocus();
            }
            break;
            default:
            {
            }
            break;
            }
            return TRUE;
        }
        default:
            break;
        }
    }  
 
    if (pMsg->hwnd == g_hWndConsole)   // 如果消息来自控制台窗口，直接返回FALSE让系统处理它们
    {
        return FALSE;
    } 
    return CDialog::PreTranslateMessage(pMsg);
}

// 辅助函数，用于将FILETIME转换为以秒为单位的时间  
double FileTimeToSeconds(const FILETIME& ft) {
    ULARGE_INTEGER uli;
    uli.LowPart = ft.dwLowDateTime;
    uli.HighPart = ft.dwHighDateTime;
    return static_cast<double>(uli.QuadPart) * 1e-7;
}

// 封装时间戳和处理器数量的结构  
struct ProcessTimeInfo {
    FILETIME prevKernelTime;
    FILETIME prevUserTime;
    std::chrono::high_resolution_clock::time_point prevTimePoint;
    DWORD processorCount;

    ProcessTimeInfo() {
        SYSTEM_INFO si;
        GetSystemInfo(&si);
        processorCount = si.dwNumberOfProcessors;
    }
};

// 获取当前进程的CPU占用率（估计值）  
double GetCpuUsage(ProcessTimeInfo& info) {
    FILETIME creationTime, exitTime, kernelTime, userTime;
    HANDLE hProcess = GetCurrentProcess();

    // 获取进程时间  
    if (!GetProcessTimes(hProcess, &creationTime, &exitTime, &kernelTime, &userTime)) {
        throw std::runtime_error("GetProcessTimes failed with error: " + std::to_string(GetLastError()));
    }

    // 计算时间差  
    std::chrono::high_resolution_clock::time_point currentTimePoint = std::chrono::high_resolution_clock::now();
    double elapsedTimeInSeconds = std::chrono::duration_cast<std::chrono::duration<double>>(currentTimePoint - info.prevTimePoint).count();

    double kernelTimeDiff = FileTimeToSeconds(kernelTime) - FileTimeToSeconds(info.prevKernelTime);
    double userTimeDiff = FileTimeToSeconds(userTime) - FileTimeToSeconds(info.prevUserTime);

    // 更新初始时间以供下一次计算  
    info.prevKernelTime = kernelTime;
    info.prevUserTime = userTime;
    info.prevTimePoint = currentTimePoint;
    // 计算CPU占用率  
    double totalCpuTime = kernelTimeDiff + userTimeDiff;
    if (totalCpuTime == 0.0) {
        return 0.0;
    }
    double cpuUsage = (totalCpuTime / (elapsedTimeInSeconds * info.processorCount)) * 100.0;
    return cpuUsage;
}

//删除过期文件的线程
void AtCodeMasterDlg::PeriodicDel1()
{
    while (1)
    {
        CString ImagePath = CommonClass::strToCstr(SaveImgPth);
        RegularFileDeletion(ImagePath, ImageSaveDay);       //删除过期图片  
        CString ImagePath2 = CommonClass::strToCstr(SaveImgPth2);
        RegularFileDeletion(ImagePath2, ImageSaveDay);       //删除过期图片  
        std::this_thread::sleep_for(std::chrono::hours(8)); //线程休眠 
    }
}
void AtCodeMasterDlg::PeriodicDel2()
{
    while (1)
    {
        CString LogPath; LogPath.Format(L"%sLog\\", AppPath.GetString());
        RegularFileDeletion(LogPath, LogSaveDay);    //删除过期日志
        std::this_thread::sleep_for(std::chrono::hours(24));    //线程休眠  
    }
}

void AtCodeMasterDlg::LogSaves(char const* LogName, const char* format, ...)
{
    va_list argptr;//参数列表
    va_start(argptr, format);
    size_t ACTSIZE = _vscprintf(format, argptr);    //内容长度，根据它给size赋值
    char* buffer = (char*)malloc(ACTSIZE + 1);      //分配内存空间
    int written = vsnprintf(buffer, ACTSIZE + 1, format, argptr); //将值加进去
    if (buffer == NULL) return;
    va_end(argptr);
    static CString FilePath;
    static SYSTEMTIME st;
    static CString strTime;
    GetLocalTime(&st);
    char tig_t1[90];
    sprintf_s(tig_t1, "%04d-%02d-%02d %02d:%02d:%02d.%03d\t", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    strTime.Format(_T("%04d-%02d-%02d"), st.wYear, st.wMonth, st.wDay);
    FilePath.Format(_T("%sLog\\%s\\"), AppPath.GetString(), strTime.GetString());
    string Path = CStringA(FilePath); 
    string LogStr(buffer);
    Logger_m logger(Path + LogName + ".txt");
    logger.writeLog(tig_t1 + LogStr);
    logger.closeLogFile();
    free(buffer);
} 
void AtCodeMasterDlg::LogSavesXls(char const* LogName, const char* format, ...)
{
    va_list argptr;//参数列表
    va_start(argptr, format);
    size_t ACTSIZE = _vscprintf(format, argptr);    //内容长度，根据它给size赋值
    char* buffer = (char*)malloc(ACTSIZE + 1);      //分配内存空间
    int written = vsnprintf(buffer, ACTSIZE + 1, format, argptr); //将值加进去
    if (buffer == NULL) return;
    va_end(argptr);
    static CString FilePath;
    static SYSTEMTIME st;
    static CString strTime;
    GetLocalTime(&st);
    char tig_t1[90];
    sprintf_s(tig_t1, "%04d-%02d-%02d %02d:%02d:%02d.%03d\t", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    strTime.Format(_T("%04d-%02d-%02d"), st.wYear, st.wMonth, st.wDay);
    FilePath.Format(_T("%sLog\\%s\\"), AppPath.GetString(), strTime.GetString());
    string Path = CStringA(FilePath); 
    string LogStr(buffer);
    Logger_m logger(Path + LogName);
    logger.writeLog(tig_t1 + LogStr);
    logger.closeLogFile();
    free(buffer); 
}
void AtCodeMasterDlg::print_a(uint8_t ux, const char* format, ...)
{
    static CEdit* print1 = (CEdit*)GetDlgItem(IDC_EDIT_Print1);
    static CEdit* print2 = (CEdit*)GetDlgItem(IDC_EDIT_Print2);
    static CEdit* print3 = (CEdit*)GetDlgItem(IDC_EDIT_Print3);
    static CEdit* print4 = (CEdit*)GetDlgItem(IDC_EDIT_Print4);
    static CEdit* print5 = (CEdit*)GetDlgItem(IDC_EDIT_Print5);
    if (!t_AllState)return;  
    va_list argptr;     //参数列表
    va_start(argptr, format);
    size_t ACTSIZE = _vscprintf(format, argptr);    //内容长度，根据它给size赋值
    char* buffer = (char*)malloc(ACTSIZE + 1);      //分配内存空间
    vsnprintf(buffer, ACTSIZE + 1, format, argptr); //将值加进去
    if (buffer == NULL) return;
    va_end(argptr); 
    int charsConverted = MultiByteToWideChar(CP_ACP, 0, buffer, -1, NULL, 0);  // 计算需要的宽字符数（不包括结尾的空字符）  
    if (charsConverted > 0)
    {
        WCHAR* str = (WCHAR*)malloc((charsConverted + 4) * sizeof(WCHAR));  // +4 为 " \r\n" 和结尾的空字符  
        if (str)
        {
            MultiByteToWideChar(CP_ACP, 0, buffer, -1, str, charsConverted + 1);  // 转换并包括结尾的空字符   
            wcscat_s(str, (charsConverted + 2 + 1), L"\r\n"); //2024-11-13优化
            if (ux == 1 && print_check[1]) { print1->SetSel(-1, -1);	print1->ReplaceSel(str); LogSavesXls("printf1.txt", "%s\n", buffer); }
            if (ux == 2 && print_check[2]) { print2->SetSel(-1, -1);	print2->ReplaceSel(str); LogSavesXls("printf2.txt", "%s\n", buffer); }
            if (ux == 3 && print_check[3]) { print3->SetSel(-1, -1);	print3->ReplaceSel(str); LogSavesXls("printf3.txt", "%s\n", buffer); }
            if (ux == 4 && print_check[4]) { print4->SetSel(-1, -1);	print4->ReplaceSel(str); LogSavesXls("printf4.txt", "%s\n", buffer); }
            if (ux == 5 && print_check[5]) { print5->SetSel(-1, -1);	print5->ReplaceSel(str); LogSavesXls("printf5.txt", "%s\n", buffer); }
            free(buffer);
        }
        else {
        }
    }
    else {
    }
}
void AtCodeMasterDlg::print_b(uint8_t ux, const char* format, ...)
{
    static CEdit* print1 = (CEdit*)GetDlgItem(IDC_EDIT_Print1);
    static CEdit* print2 = (CEdit*)GetDlgItem(IDC_EDIT_Print2);
    static CEdit* print3 = (CEdit*)GetDlgItem(IDC_EDIT_Print3);
    static CEdit* print4 = (CEdit*)GetDlgItem(IDC_EDIT_Print4);
    static CEdit* print5 = (CEdit*)GetDlgItem(IDC_EDIT_Print5);
    if (!t_AllState)return;
    va_list argptr;     //参数列表
    va_start(argptr, format);
    size_t ACTSIZE = _vscprintf(format, argptr);    //内容长度，根据它给size赋值
    char* buffer = (char*)malloc(ACTSIZE + 1);      //分配内存空间
    vsnprintf(buffer, ACTSIZE + 1, format, argptr); //将值加进去
    if (buffer == NULL) return;
    va_end(argptr);
    //WCHAR str[4096];
    //MultiByteToWideChar(CP_ACP, 0, buffer, strlen(buffer) + 1, str, sizeof(str) / sizeof(str[0]));
    int charsConverted = MultiByteToWideChar(CP_ACP, 0, buffer, -1, NULL, 0);  // 计算需要的宽字符数（不包括结尾的空字符）  
    if (charsConverted > 0)
    {
        WCHAR* str = (WCHAR*)malloc((charsConverted + 4) * sizeof(WCHAR));  // +4 为 " \r\n" 和结尾的空字符  
        if (str)
        {
            MultiByteToWideChar(CP_ACP, 0, buffer, -1, str, charsConverted + 1);  // 转换并包括结尾的空字符   
            //wcscat_s(str, (charsConverted + 2 + 1), L"\r\n"); //2024-11-13优化
            if (ux == 1 && print_check[1]) { print1->SetSel(-1, -1);	print1->ReplaceSel(str); LogSavesXls("printf1.txt", "%s\n", buffer); }
            if (ux == 2 && print_check[2]) { print2->SetSel(-1, -1);	print2->ReplaceSel(str); LogSavesXls("printf2.txt", "%s\n", buffer); }
            if (ux == 3 && print_check[3]) { print3->SetSel(-1, -1);	print3->ReplaceSel(str); LogSavesXls("printf3.txt", "%s\n", buffer); }
            if (ux == 4 && print_check[4]) { print4->SetSel(-1, -1);	print4->ReplaceSel(str); LogSavesXls("printf4.txt", "%s\n", buffer); }
            if (ux == 5 && print_check[5]) { print5->SetSel(-1, -1);	print5->ReplaceSel(str); LogSavesXls("printf5.txt", "%s\n", buffer); }
            free(buffer);
        }
        else {
            // 内存分配失败处理  
        }
    }
    else {
        // MultiByteToWideChar 转换失败处理  
    }
}
void AtCodeMasterDlg::CameraState()
{
}
//参数获取按钮
void AtCodeMasterDlg::OnBnClickedGetParameterButton()
{
    if (Dev.Hik0.OnDevNum > 0)      Hik0_GetParameter();        //相机参数获取 
    if (Dev.Hik1.OnDevNum > 0)      Hik1_GetParameter();        //相机参数获取 {fs}-515-73515199845690;;;433575342290703-00062
    if (Dev.Dh1.CheckNum > 0)       DaHua1_GetParameter();      //华睿智能相机参数获取 
    if (Dev.Zw0.CheckNum > 0)       Zk0_GetParameter(0);        //中微
}
//相机参数设置按钮
void AtCodeMasterDlg::OnBnClickedSetParameterButton()
{
    CString cstr;
    if (Dev.Hik0.OnDevNum > 0)      Hik0_SetParameter(2);   //工业相机参数设置
    if (Dev.Hik1.OnDevNum > 0)      Hik1_SetParameter(2);   //智能相机参数设置  
    if (Dev.Dh1.CheckNum > 0)       DaHua1_SetParameter();  //华睿智能相机参数设置 
    if (Dev.Zw0.CheckNum > 0)       Zk0_SetParameter(2);    //中微
     
    ((CEdit*)GetDlgItem(IDC_Edit_HFOV))->GetWindowText(cstr); 
    WritePrivateProfileStringW(_T("DynamicBinding"), _T("IDC_Edit_HFOV"), cstr, Oth.GetAppPath() + L"Setting/Config.ini");
    HFOV = _ttoi(cstr);    //视野宽

    ((CEdit*)GetDlgItem(IDC_Edit_VFOV))->GetWindowText(cstr); 
    WritePrivateProfileStringW(_T("DynamicBinding"), _T("IDC_Edit_VFOV"), cstr, Oth.GetAppPath() + L"Setting/Config.ini");
    VFOV = _ttoi(cstr);    //视野高

    print_a(5, "视野左到右耗时(t=v/s)%.1fms,假设速度是%.2fm/s", float(HFOV / (Set.TraySpeed )), Set.TraySpeed);
    print_a(5, "视野顶到底耗时(t=v/s)%.1fms,假设速度是%.2fm/s", float(VFOV / (Set.TraySpeed )), Set.TraySpeed);
}
//读码按钮
void AtCodeMasterDlg::AllCameraCodesStart()
{
    if (Dev.Hik0.CheckNum > 0)
        Hik0_CamStart();        //海康工业相机
    if (Dev.Hik1.CheckNum > 0)
        Hik1_CamStart();        //海康智能相机
    if (Dev.Dh1.CheckNum > 0)
        DaHua1_CamStart();      //华睿智能相机
    if (Dev.Zw0.CheckNum > 0)
        ZhongWei0_CamStart();   //中科微至相机
}
//工业相机重连 
void AtCodeMasterDlg::Camera0Reconnect()
{
    SYSTEMTIME st;
    GetLocalTime(&st);
    char tig_now[64];
    sprintf_s(tig_now, "%04d-%02d-%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    static string tig_t13;
    for (uint8_t num = 0; num < Dev.Hik0.CheckNum; num++)
    {
        if (Dev.Hik0.OnDevNum < Dev.Hik0.CheckNum)
        {
            if (Dev.Hik0.DevPro[num])continue;
            print_a(5, "选择了%d个工业相机，打开了%d个 正在重新连接,检查网口配置和相机网线！", Dev.Hik0.CheckNum, Dev.Hik0.OnDevNum);
            if (Dev.Hik0.state == 0)
            {
                Dev.Hik0.state = 1;
                exception_state("扫码软件", "32", "相机初次打开失败", "01", tig_now, 1, "", 2);
            }
            Camera0Rec = true;
            Hik0_CamStart();
        }
        else
        {
            if (Dev.Hik0.state == 1)
            {
                Dev.Hik0.state = 0;
                exception_state("扫码软件", "32", "相机初次打开失败，已恢复正常", "00", tig_now, 4, tig_t13, 2);
            }
            KillTimer(21);
        }
    }
}
//智能相机重连
void AtCodeMasterDlg::Camera1Reconnect()
{
    SYSTEMTIME st;
    GetLocalTime(&st);
    char tig_now[64];
    sprintf_s(tig_now, "%04d-%02d-%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    static string tig_t13;
    for (uint8_t num = 0; num < Dev.Hik1.CheckNum; num++)
    {
        if (Dev.Hik1.OnDevNum < Dev.Hik1.CheckNum)
        {
            if (Dev.Hik1.DevPro[num])continue;
            print_a(5, "选择了%d个智能相机，打开了%d个 正在重新连接,检查网口配置和相机网线！", Dev.Hik1.CheckNum, Dev.Hik1.OnDevNum);
            if (Dev.Hik1.state == 0)
            {
                Dev.Hik1.state = 1;
                exception_state("扫码软件", "32", "相机初次打开失败", "01", tig_now, 1, "", 2);
            }
            Camera1Rec = true;
            Hik1_CamStart();
        }
        else 
        {
            if (Dev.Hik1.state == 1)
            {
                Dev.Hik1.state = 0;
                exception_state("扫码软件", "32", "相机初次打开失败，已恢复正常", "00", tig_now, 4, tig_t13, 2);
            }
            KillTimer(22);
        }
    }
}
//中科微至相机重连
void AtCodeMasterDlg::ZhongWeiReconnect()
{
    SYSTEMTIME st;
    GetLocalTime(&st);
    char tig_now[64];
    sprintf_s(tig_now, "%04d-%02d-%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    static string tig_t13;
    QuickScanStatus ret;
    for (uint8_t num = 0; num < Dev.Zw0.CheckNum; num++)
    {
        if (Dev.Zw0.OnDevNum < Dev.Zw0.CheckNum)
        {
            if (Dev.Zw0.DevPro[num])continue;
            print_a(5, "中科相机初次打开失败IP:%s,请重启软件,检查网口配置和相机网线！ ", (CStringA)Dev.Zw0.Ip[num]);
            ret = QuickScanSdk_StopQuickScanSystem();  //关闭读码系统 
            if (ret != QUICK_SCAN_SUCCESS)
            {
                print_a(1, "Error:中科微至相机关闭读码系统失败,错误码(%#x) ", ret);
            }
            else  QuickScanSdk_StartQuickScanSystem(); //开启读码系统
            Zk0_SetParameter(1);
            Zk0_GetParameter(0);
            if (Dev.Zw0.state == 0)
            {
                Dev.Zw0.state = 1;
                exception_state("扫码软件", "32", "相机初次打开失败", "01", tig_now, 1, "", 2);
            }
        }
        else
        {
            if (Dev.Zw0.state == 1)
            {
                Dev.Zw0.state = 0;
                exception_state("扫码软件", "32", "相机初次打开失败，已恢复正常", "00", tig_now, 4, tig_t13, 2);
            } 
            KillTimer(23);
        }
    }
}
void AtCodeMasterDlg::OnBnClickedButton1()
{
    int* arr = (int*)malloc(99999 * 99999);
    free(arr); // 仅释放部分内存，留下内存泄漏
    for (int i = 0; i < 5; ++i)
    {
        print_a(5, "测试:复现界面假死:使用内存区域的指针数组进行操作，但未释放这些指针，导致内存泄漏  ptrs[%d]: %d\n", i, arr[i]);
    }
}

void AtCodeMasterDlg::OnClose()
{
    CDialogEx::OnClose();
}
//窗口即将销毁
void AtCodeMasterDlg::OnDestroy()
{
    Sleep(50);
    CloseAllApp();
    CDialogEx::OnDestroy();
}

void AtCodeMasterDlg::CloseAllApp()
{
    CString StrMsg;
    sndPlaySound(NULL, SND_PURGE);//清除声音缓冲区
    t_AllState = 0;
    if (Dev.Hik0.OnDevNum > 0)
        Hik0_CamStop();     //退出工业相机
    if (Dev.Hik1.OnDevNum > 0)
        Hik1_CamStop();     //退出智能相机
    if (Dev.Dh1.CheckNum > 0)
        DaHua1_CamStop();   //关闭华睿智能相机 
    if (Dev.Zw0.OnDevNum > 0)
        QuickScanSdk_StopQuickScanSystem(); //关闭读码系统

    CloseTcp(1);
    CloseTcp(2);
    CloseTcp(3);
    CloseTcp(4);
    CloseTcp(5);
    //CloseTcpServer(6);
    CloseTcp(7);
    CloseUdp(1);
    CloseUdp(2);
    if (Ftp_ConStatus == true)
    {
        Ftp_pConnection->Close();  //关闭FTP
        Ftp_ConStatus = false;
    }
    if (Set.Uart1_ConStatus == true)
    {
        A1_CSerialPort.CloseListenTread();//断开串口连接 
        Set.Uart1_ConStatus = false;
    }
    if (Set.Uart2_ConStatus == true)
    {
        Set.Uart2_ConStatus = false;
        Usart2Close(2);
    }
    if (Set.Uart3_ConStatus == true)
    {
        Set.Uart3_ConStatus = false;
        Usart2Close(3);
    }
    ////hMessageShm.Close();    //释放虚拟内存     
    //HANDLE mainThread = GetCurrentProcess();   //获取当前窗口的伪句柄
    //TerminateProcess(mainThread, 0);           //终止进程   
}

//获取、设置指定相机的参数
void AtCodeMasterDlg::OnCbnSelendokCombo1Parameter()
{
} 
//电脑关机
void AtCodeMasterDlg::OnEndSession(BOOL bEnding)
{
    CDialogEx::OnEndSession(bEnding);
    CloseAllApp();
}


//触发极性
void AtCodeMasterDlg::OnCbnSelendokLineouthardtriggeractive()
{ 
}
